<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html;charset=UTF-8"/>
    <title>网页版扫雷</title>
    <style type="text/css">
    body{text-align:center;background-color:#ffffff; }
    table{border:1px solid #888888;border-collapse:collapse;margin: auto;margin-top: 10px;}
    td,.noFlag,.flag_mine{
        border:1px solid #888888;font-weight:900;background-color: #cccccc;
        width:25px;height:25px;font-size :18;cursor:hand;text-align:center;font-size:18px;
        background-repeat:no-repeat background-position:center;
    }
    td.flag_0{ background-color:#FFFFFF;}
    td.flag_1{ background-color:#FFFFFF;color:#0000FF;}
    td.flag_2{ background-color:#FFFFFF;color:#008000;}
    td.flag_3{ background-color:#FFFFFF;color:#FF0000;}
    td.flag_4{ background-color:#FFFFFF;color:#000080;}
    td.flag_5{ background-color:#FFFFFF;color:#800000;}
    td.flag_6{ background-color:#FFFFFF;color:#008080;}
    td.flag_7{ background-color:#FFFFFF;color:#000000;}
    td.flag_8{ background-color:#FFFFFF;color:#808080;}
    #time,#mine_num{width : 80px color:white}
    td.flag{ background-image : url(image/flag.png)
    ;background-color :#FFFFFF;}
    </style>
    <script type="text/javascript">
        var rn=10,cn=10; //雷区行、列
        var bombnum=10;//雷数
        var bombarr=null;//雷区数组
        var table=null;//雷区table
        var seconds=0;//用时
        var timer=null;//计时器
        //开始游戏
        function start(){
            seconds=0;//计时清零
            clearInterval(timer);//删除计时器
            init();//随机布雷
            createMine();//画雷区
            timer=setInterval(recordTime,1000);//初始化定时器
            mine_num.innerHTML="雷数："+bombnum;//显示雷数
            }
        //计时
        function recordTime(){
            seconds++;
            time.innerHTML="time:"+seconds+"s";
        }
        //每个单元格的对象
        function Obj(){
            this.rownum=arguments[0];
            this.colnum=arguments[1];
            this.isMine=arguments[2];
            this.aroundMinenum=arguments[3];
        }
        //随机布雷
        function init(){
            bombarr=new Array(rn);
            var bombtemp=new Array(rn*cn);
            var bombs=new Array(bombnum);
            var len=bombtemp.length;
            for(var i=0;i<len;i++){
                bombtemp[i]=i+1;
            }
            //从数组bombtemp中随机选取bombnum个不重复的值
            for(var i=0;i<bombnum;i++){
                var r=Math.floor(Math.random()*len);//取0-len的随机数，不包括len
                bombs[i]=bombtemp[r];
                var temp=bombtemp[r];
                bombtemp[r]=bombtemp[len-1];
                bombtemp[len-1]=temp;
                len=len-1;
            }
            //初始化雷区
            for(var i=0;i<rn;i++){
                var rarr=new Array(cn);
                for(var j=0;j<cn;j++){
                    var flag=0;
                    var o=new Obj(i,j);
                    for(var k=0;k<bombs.length;k++){
                        if(i*cn+j+1==bombs[k]){
                            o.isMine=true;
                            flag=1;
                            break;
                        }
                    }
                    if(flag==0){
                        o.isMine=false;
                    }
                    rarr[j]=o;
                }
                bombarr[i]=rarr;
            }
            //计算某一节点周围雷数
            for(var i=0;i<bombarr.length;i++){
                var rarr=bombarr[i];
                for(var j=0;j<rarr.length;j++){
                    var o=rarr[j];
                    var cnt=0;
                    for(var k=i-1;k<i+2;k++){
                        for(var l=j-1;l<j+2;l++){
                            if(k==i&&l==j){
                                continue;
                            }
                            if(bombarr[k]&&bombarr[k][l]){
                                if(bombarr[k][l].isMine){
                                    cnt++;
                                }
                            }
                        }
                    }
                    o.aroundMinenum=cnt;
                }
            }
        }
        //画雷区(表格)
        function createMine(){
            mine.innerHTML="";
            var rnum=rn;
            var cnum=cn;
            table=document.createElement("table");
            for(var i=0;i<rnum;i++){
                var tr=table.insertRow(table.rows.length);
                for(var j=0;j<cnum;j++){
                    var td=tr.insertCell(tr.cells.length);
                    if(bombarr[i][j].isMine){
                        td.className="flag_mine";
                    }else{
                        td.className="noFlag";
                    }
                    //注册事件
                    td.onmousedown=tdClick;
                }
            }
            mine.appendChild(table);
        }
        //鼠标按下事件
        var tdClick=function (e){
            var e=window.event||e;
            if(e.button==0||e.button==1){   //左击
                if(this.className=="noFlag"||this.className=="flag_mine"){
                    var o=bombarr[this.parentElement.rowIndex][this.cellIndex];
                    if(o.isMine){   //点中雷，结束游戏
                        displayAll();
                        this.style.backgroundImage="url(image/mine2.jpg)";
                        clearInterval(timer);
                        alert("Game Over !");
                    }else{
                        check(this);
                    }
                    checkIsWin();
                }
            }else if(e.button==2){  //右击
                flagOrCancel(this);
            }
        }
        //右击，标记
        function flagOrCancel(obj){
            var cln=obj.className;
            if(cln=="flag"){
                var rnum=obj.parentElement.rowIndex;
                var cnum=obj.cellIndex;
                if(bombarr[rnum][cnum]){
                    obj.className="flag_mine";
                }else{
                    obj.className="noFlag";
                }
            }else if(cln=="noFlag"||cln=="flag_mine"){
                obj.className="flag";
            }
        }
        //左击，检测周围雷的遍布，递归算法
        function check(obj){
            var cnt=0;
            var cnum=obj.cellIndex;
            var rnum=obj.parentElement.rowIndex;
            var o=bombarr[rnum][cnum];
            if(o.aroundMinenum>0){
                obj.className="flag_"+o.aroundMinenum;
                obj.appendChild(document.createTextNode(o.aroundMinenum));
                obj.onmousedown=function(){};
                return;
            }else{
                obj.className="flag_0";
                obj.onmousedown=function(){};
            }
            for(var i=rnum-1;i<rnum+2;i++){
                for(var j=cnum-1;j<cnum+2;j++){
                    if(rnum==i&&cnum==j){
                        continue;
                    }
                    var r=table.rows[i];
                    if(r){
                        var c=r.cells[j];
                        if(c){
                            if(c.className=="noFlag"){
                                check(c); //递归
                                               }
                        }
                    }
                }
            }
        }
        //获取行数、列数、地雷数
        function levelChange(){
            var op=level.options[level.selectedIndex];
            var varr=op.value.split(',');
            cn=varr[0];
            rn=varr[1];
            bombnum=varr[2];
        }
        //结束游戏，显示地雷分布情况
        function displayAll(){
            for(var i=0;i<rn;i++){
                var tr=table.rows[i];
                for(var j=0;j<cn;j++){
                    var td=tr.cells[j];
                    if(td.className=="flag_mine"){
                        td.style.backgroundImage="url(image/mine.jpg)";
                        td.style.backgroundColor="white";
                    }else if(td.className=="flag"){
                        if(!bombarr[i][j].isMine){
                            td.style.backgroundImage="url(image/mine3.jpg)";
                            td.style.backgroundColor="white";
                        }
                    }
                    td.onmousedown=function(){};
                }
            }
        }
        //检查是否赢了
        function checkIsWin(){
            var value=rn*cn-bombnum;
            var cname;
            var cnt=0;
            for(var i=0;i<rn;i++){
                var tr=table.rows[i];
                for(var j=0;j<cn;j++){
                    var td=tr.cells[j];
                    cname=td.className.charAt(td.className.length-1);
                    if(!isNaN(cname)){
                        cnt++;
                    }
                }
            }
            //如果赢了
            if(cnt==value){
                //清除定时器
                clearInterval(timer);
                //把所有的雷节点，背景都设置为flag
                for(var i=0;i<rn;i++){
                    var tr=table.rows[i];
                    for(var j=0;j<cn;j++){
                        var td=tr.cells[j];
                        if(td.className=="noFalg"||td.className=="flag_mine"){
                            td.className="flag";
                        }
                        td.onmousedown=function(){};
                    }
                }
                alert("You Win ! time:"+seconds+"s.");
            }
        }
        window.onload=function(){
            //屏蔽右键菜单
            document.oncontextmenu=function(evt){
                if (window.event){
                    window.event.returnValue = false;
                }else{
                    evt.preventDefault();
                }
            };
            level.onchange=levelChange;
            levelChange();
        }
    </script>
</head>
<body>
<button onClick="start()">开始游戏</button>
<select id="level">
    <option value="10,10,10">初级</option>
    <option value="16,12,24">中级</option>
    <option value="20,16,40">高级</option>
</select>
<span id="mine_num">雷数：0</span>
<span id="time">time:0s</span>
<div id="mine"></div>
</body>
</html>